# application/auth/auth_service.py
import datetime
import hashlib
from app.utils.verify_code import VerifyCode
from app.models.sys_manage.user import User


class AuthService:
    def __init__(self, mysql_tool, redis_tool):
        self.mysql_tool = mysql_tool
        self.redis_tool = redis_tool

    def verify_password(self, stored_password, input_password):
        """
        验证密码是否匹配
        :param stored_password: 数据库中存储的哈希密码
        :param input_password: 用户输入的已经经过前端SHA256哈希的密码
        :return: 是否匹配
        """
        return stored_password == input_password

    def verify_login(self, username, password, code_id, captcha):
        """
        验证登录信息
        :param username: 用户名
        :param password: 已经过SHA256哈希的密码
        :param code_id: 验证码ID
        :param captcha: 验证码
        :return: 错误信息，如果验证通过返回空字符串
        """
        if not username or not password:
            error_message = "用户名或密码不能为空"
        elif not code_id or not captcha:
            error_message = "验证码不能为空"
        elif self.redis_tool.get_value(code_id) is None:
            error_message = "验证码已过期，请重新获取！"
        elif self.redis_tool.get_value(code_id).upper().decode("utf-8") != captcha.upper():
            error_message = "验证码错误，请重新输入！"
        else:
            users = self.mysql_tool.query_data(User, username=username)
            if not users:
                error_message = "用户不存在，请重新输入！"
            elif users[0].is_disabled:
                error_message = "账号已禁用！"
            elif users[0].is_locked and abs(datetime.datetime.now() - users[0].locked_date) < datetime.timedelta(
                    minutes=30):
                self._handle_login_failure(users[0])
                error_message = "账号已锁定，请30分钟后重试！"
            elif not self.verify_password(users[0].password, password):
                error_message = "密码错误，请重新输入！"
                self._handle_login_failure(users[0])
            else:
                self._handle_login_success(users[0])
                # 登录成功，直接返回当前用户
                return "", users[0]
        return error_message, None

    def _handle_login_failure(self, user):
        """处理登录失败逻辑"""
        user.failed_time += 1
        user_filter = User(user_id=user.user_id)
        current_date = datetime.datetime.now()

        if user.failed_time > 4:
            user_update = User(
                is_locked=True,
                failed_time=user.failed_time,
                last_failed_date=current_date,
                locked_date=current_date
            )
        else:
            user_update = User(
                failed_time=user.failed_time,
                last_failed_date=current_date
            )

        self.mysql_tool.update_data(User, user_filter, user_update)

    def _handle_login_success(self, user):
        """处理登录成功逻辑"""
        user_filter = User(user_id=user.user_id)
        current_date = datetime.datetime.now()
        user_update = User(
            is_locked=False,
            failed_time=0,
            last_success_date=current_date,
            locked_date=None
        )
        self.mysql_tool.update_data(User, user_filter, user_update)

    def generate_captcha(self):
        """
        生成验证码
        :return: 包含验证码ID和URL的字典
        """
        verify_code = VerifyCode()
        # 将验证码id，code值存入redis中，有效期5分钟
        self.redis_tool.set_value(verify_code.codeId, verify_code.code, 5 * 60)
        # 将 VerifyCode 对象的属性转换为字典
        response_data = {
            'codeId': verify_code.codeId,
            'codeUrl': verify_code.codeUrl,
        }
        return response_data
